﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CubicFWNet.Common
{
    public static class CompareObj
    {
        /// <summary>
        /// 比较两个对象中的属性差别 并返回描述字符串   若是比较的类中有类属性变量的话，在类属性中注明属性并在该类中的比较属性中注明 [Description("ID")] 即能多层比较
        /// </summary>
        /// <param name="oldObject">比较对象1</param>
        /// <param name="newObject">比较对象2</param>
        /// <param name="tag">描述的前缀标记 默认为空即可</param>
        /// <param name="isOnlyHasDescription">是否只比较有描述标记的属性,默认为true,只比较标记了 </param>
        /// <returns>返回差异描述的字符串列表</returns>
        public static string Compare(this Object oldObject, Object newObject, string tag = "", bool isOnlyHasDescription = true)
        {
            if (oldObject == null || newObject == null)
            {
                return "[]";
            }
            StringBuilder strJson = new StringBuilder();
            strJson.Append("[");
            List<string> list = new List<string>();
            var type = oldObject.GetType();
            foreach (var s in type.GetProperties())
            {
                object[] objs = s.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute), false);
                if ((objs != null && objs.Length != 0) || !isOnlyHasDescription)
                {
                    string desTitle = "";
                    if (isOnlyHasDescription)
                    {
                        System.ComponentModel.DisplayNameAttribute da = (System.ComponentModel.DisplayNameAttribute)objs[0];
                        desTitle = da.DisplayName;
                    }
                    else
                    {
                        desTitle = s.Name;
                    }
                    var value1 = s.GetValue(oldObject);
                    var value2 = s.GetValue(newObject);
                    if (s.PropertyType.IsClass && s.PropertyType.Name != "String" && s.PropertyType.Name != typeof(List<>).Name)
                    {
                        //list.AddRange(value1.Compare(value2, desTitle));
                        strJson.Append(value1.Compare(value2, desTitle));
                    }
                    else
                    {
                        /**
                         * tyj 将 value2 改为 value2.ToString()
                         */
                        if (value1 != null && value2 != null)
                        {
                            if (value1.ToString() != value2.ToString())
                            {
                                //list.Add(string.Format("[{0}]由[{1}]改变为[{2}]!", tag + desTitle, value1, value2.ToString()));
                                strJson.Append("{");
                                strJson.Append("\"name\":\"" + s.Name + "\",");
                                strJson.Append("\"des\":\"" + desTitle + "\",");
                                strJson.Append("\"before\":\"" + value1.ToString() + "\",");
                                strJson.Append("\"after\":\"" + value2.ToString() + "\",");
                                strJson.Append("},");
                            }
                        }
                        else if (value1 == null && value2 != null)
                        {
                            //list.Add(string.Format("[{0}] 设置值为[{1}]!", tag + desTitle, value2.ToString()));
                            strJson.Append("{");
                            strJson.Append("\"name\":\"" + s.Name + "\",");
                            strJson.Append("\"des\":\"" + desTitle + "\",");
                            strJson.Append("\"before\":\"\",");
                            strJson.Append("\"after\":\"" + value2.ToString() + "\",");
                            strJson.Append("},");
                        }
                    }
                }
            }
            strJson.Append("]");
            return strJson.ToString();
        }

        public static string TODescriptionJson(this Object obj, bool isOnlyHasDescription = true)
        {
            if (obj == null)
            {
                return "[]";
            }
            StringBuilder strJson = new StringBuilder();
            strJson.Append("[");
            var type = obj.GetType();
            var propertyInfos = type.GetProperties();
            foreach (var s in type.GetProperties())
            {
                object[] objs = s.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute), false);
                if ((objs != null && objs.Length != 0) || !isOnlyHasDescription)
                {
                    string desTitle = "";
                    if (isOnlyHasDescription)
                    {
                        System.ComponentModel.DisplayNameAttribute da = (System.ComponentModel.DisplayNameAttribute)objs[0];
                        desTitle = da.DisplayName;
                    }
                    else
                    {
                        desTitle = s.Name;
                    }
                    var value1 = s.GetValue(obj);

                    if (s.PropertyType.IsClass && s.PropertyType.Name != "String" && s.PropertyType.Name != typeof(List<>).Name)
                    {
                        strJson.Append(value1.Compare(desTitle));
                    }
                    else
                    {
                        if (value1 != null)
                        {
                            strJson.Append("{");
                            strJson.Append("\"name\":\"" + s.Name + "\",");
                            strJson.Append("\"des\":\"" + desTitle + "\",");
                            strJson.Append("\"before\":\"" + value1.ToString() + "\",");
                            strJson.Append("\"after\":\"\",");
                            strJson.Append("},");
                        }
                    }
                }
            }
            strJson.Append("]");
            return strJson.ToString();
        }
    }
}
